<?php

namespace App\Http\Controllers\Api\v1\User;

use App\Http\Controllers\Api\BaseController;
use App\Models\Api\Recode;
use App\Models\Api\RecodeCat;
use App\Models\Api\Orders;
use App\Models\Api\Rectification;
use App\Models\Api\User;
use Cache;
use DB;
use Illuminate\Http\Request;

/**
 * @title
 * @desc
 * @url
 * @version 2.0.0
 * Class Demo
 * @package app\api\controller\v2
 */
class InfoController extends BaseController
{
    protected $restActionList = ['index', 'read', 'save', 'update', 'delete'];
    protected $noNeedJudgeSummer = ['香港特别行政区', '澳门特别行政区', '台湾省', '北美洲', '大洋洲', '非洲', '南美洲', '欧洲', '亚洲'];

    protected $RecodeModel;

    protected $RecodeCatModel;

    public function __construct()
    {
        //parent::__construct();

        $this->RecodeModel = new Recode();

        $this->RecodeCatModel = new RecodeCat();
    }

    /**
     * @title
     * @method GET
     * @desc  获取个人中心数据
     * @return array
     */
    public function index(Request $request)
    {
        if (!Request()->isMethod('get')) {
            return show(config('code.error'), '未知操作', [], 403);
        }
        try
        {
            $where = ['r.uid' => $request->uid, 'r.isself' => 1];
            $data  = User::from('user as u')
                ->select('r.name', 'r.year', 'r.isself', 'r.month', 'r.day', 'r.hour', 'r.minute', 'r.timezone', 'r.birth_country', 'r.birth_province', 'r.birth_city', 'r.long_deg', 'r.long_min', 'r.ew', 'r.lat_deg', 'r.lat_min', 'r.ns', 'u.avatar', 'w.nickname', 'u.sex', 'u.tel')
                ->join('recode as r', 'r.uid', '=', 'u.id', 'LEFT')
                ->join('wechat as w', 'u.id', '=', 'w.uid', 'LEFT')
                ->where($where)
                ->firstOrFail();
            if ($data['month'] < 10) {
                $data['month'] = '0' . $data['month'];
            }
            if ($data['day'] < 10) {
                $data['day'] = '0' . $data['day'];
            }
            if ($data['hour'] < 10) {
                $data['hour'] = '0' . $data['hour'];
            }
            if ($data['minute'] < 10) {
                $data['minute'] = '0' . $data['minute'];
            }
            $field         = ['id', 'status'];
            $where         = ['uid' => $request->uid, 'status' => ['eq', 1]];
            $rectification = (new Rectification())
                ->select($field)
                ->where($where)
                ->count('id');

            if ($rectification > 0) {
                $data['is_rectification'] = 1;
            } else {
                $data['is_rectification'] = 0;
            }

        } catch (\Exception $e) {
            return show(config('code.denied'), '用户信息获取失败,请重新登录');
        }
        if (!$data['sex']) {
            $data['sex'] = 1;
        }
        if ($data['tel']) {
            $data['tel'] = substr_replace($data['tel'], '****', 3, 4);
        }

        return show(200, '成功', $data);
    }
    /**
     * @title
     * @method GET
     * @desc   个人中心绑定手机号
     * @return array
     */
    public function bind_tel(Request $request)
    {
        if (!Request()->isMethod('post')) {
            return show(config('code.error'), '未知操作', [], 403);
        }
        $tel  = $request->input('tel');
        $code = $request->input('code');
        if (!$tel || !$code || strlen($code) != 6) {
            return show(config('code.error'), '验证码错误');
        }
        if (!preg_match("/^1[3456789]{1}\d{9}$/", $tel)) {
            return show(config('code.error'), '手机号无效');
        }
        $time = time(); // 当前时间  有效时间暂定为十分钟 600s
        // 判断给手机是否已经注册过
        $user = User::select('id', 'tel', 'nickname', 'avatar', 'forbidden', 'email', 'is_first_login', 'uc_id', 'has_self_recode')
            ->where(['tel' => $tel])
            ->first();
        if (empty($user) || $user === null) {
            // 若未注册
            try
            {
                // 判断code是否正确
                $data = DB::table('tel_login')->where(['tel' => $tel, 'code' => $code])->first();
                // code输入错误
                if (empty($data)) {
                    return show(config('code.error'), '验证码错误');
                } else {
                    // 判断code是否过期
                    if ($data->expire_time < $time) {
                        return show(config('code.error'), '验证码过期');
                    }
                    // 开始绑定手机号
                    $result = User::where('id', $request->uid)->update(['tel' => $tel]);
                    return show(200, '绑定成功');
                }

            } catch (\Exception $e) {
                return show(config('code.error'), $e->getMessage());
            }
        } else {
            return show(config('code.error'), '该手机号已被其他账号绑定');
        }
    }
    /**
     * @title
     * @method POST
     * @desc  更换手机
     */
    public function change_tel(Request $request)
    {
        if (!Request()->isMethod('put')) {
            return show(config('code.error'), '未知操作', [], 403);
        }

        $old_tel = $request->input('old_tel');
        $tel     = $request->input('tel');
        $code    = $request->input('code');

        if (!$old_tel || !$tel || !$code || strlen($code) != 6) {
            return show(config('code.error'), '验证码错误');
        }
        if (!preg_match("/^1[3456789]{1}\d{9}$/", $tel)) {
            return show(config('code.error'), '手机号无效');
        }
        $time = time(); // 当前时间  有效时间暂定为十分钟 600s

//        判断原手机号是否正确
        try{

        $old = (new User())->where(['id' => $request->uid, 'tel' => $old_tel])
            ->first(['tel']);

        // 判断给手机是否已经注册过
        $user = User::select('tel')
            ->where(['tel' => $tel])
            ->first();
       }catch (\Exception $e)
       {
            return show(config('code.error'),'获取用户手机号失败');
        }

        if (empty($old) || $old === null) {
            return show(config('code.error'), '原手机号错误');
        }

        // 若未注册
        if(empty($user) || $user === null)
        {
            try{
                // 判断code是否正确
                $data = DB::table('tel_login')->where(['tel'=>$tel,'code'=>$code])->first();
            }catch (\Exception $e)
            {
                return show(config('code.error'),'查询验证码失败');
            }
            // code输入错误
            if(empty($data))
            {
                return show(config('code.error'), '验证码错误');
            }
            else
            {
//                // 判断code是否过期
                if ($data->expire_time < $time)
                {
                    return show(config('code.error'), '验证码已过期');
                }

                try{
                    $result = (new User())->where(['id'=>$request->uid])->update(['tel' => $tel]);
                }catch (\Exception $e)
                {
                    $result = false;
                }
                // 开始绑定手机号
                if ($result)
                {
                    return show(config('code.success'), '绑定成功');
                }else{
                    return show(config('code.error'), '绑定失败');
                }
            }
        }
        return show(config('code.error'),'该手机号已被其他账号绑定');
    }

    /**
     * @title
     * @method PUT
     * @desc  修改档案出生时间
     * @return array
     */
    public function alter_time(Request $request)
    {
        if (!Request()->isMethod('put')) {
            return show(config('code.error'), '未知操作', [], 403);
        }
        $year  = $request->input('year'); // 出生时间-年
        $month = $request->input('month'); // 出生时间-月
        $uid   = $request->uid;
        if ($month < 10) {
            $month = '0' . $month;
        }
        $day = $request->input('day'); // 出生时间-日
        if ($day < 10) {
            $day = '0' . $day;
        }
        $hour = $request->input('hour'); // 出生时间-时
        if ($hour < 10) {
            $hour = '0' . $hour;
        }
        $minute = $request->input('minute'); // 出生时间-分
        if ($minute < 10) {
            $minute = '0' . $minute;
        }
        $timezone  = $request->input('timezone',8); // 出生时间-时区
       // $is_summer = isSummerTime($hour, $minute, 0, $month, $day, $year) ? 1 : 0; // 是否开启夏令时
         // 获取档案信息
        try{
            $recode_old = $RecodeModel->getSelfRecode(['uid'=>$uid]);
        }catch (\Exception $e)
        {
            return show(config('code.error'),'获取档案信息失败');
        }

        if (!in_array($recode_old['birth_country'], $this->noNeedJudgeSummer))
        {
            $is_summer = isSummerTime($hour,$minute,0,$month,$day,$year) ? 1 : 0;// 是否开启夏令时
        }else{
            $is_summer = 0;
        }

        $data = [
            'year'      => $year,
            'month'     => $month,
            'day'       => $day,
            'hour'      => $hour,
            'minute'    => $minute,
            'timezone'  => $timezone,
            'is_summer' => $is_summer,
        ];
//       检查档案时间格式
        checkRecodeData($year, $month, $day, $hour, $minute, $timezone);

        // 获取档案信息
        $recode_old = $this->RecodeModel->getSelfRecode(['uid' => $uid]);
        //获取档案所属档案袋id
        $recode_cat_id = $this->RecodeCatModel->getRecodeCatId(['uid' => $uid, 'rid' => $recode_old['id']]);
        // 编辑档案前检测是否 有相关订单
        $rec = $this->RecodeModel->checkAboutOrders(['uid' => $uid, 'id' => $recode_old['id']]);

        // 若有，则档案时间只能为当天内变动，若跨日期，则只能在两小时以内变动
        if ($rec) {
            // 判断or_day是否存在
            if (empty($recode_old['or_day']) || !$recode_old['or_day']) {
                $recode_old['or_day'] = $recode_old['day'];
                $data['or_day']       = $recode_old['day'];
            }

            $time = strtotime($recode_old['year'] . '-' . $recode_old['month'] . '-' . $recode_old['or_day'] . ' 12:00');
            $max  = $time + 3600 * 14;
            $min  = $time - 3600 * 14;

            $now_time = $time = strtotime($year . '-' . $month . '-' . $day . ' ' . $hour . ':' . $minute);

            if ($now_time > $max || $now_time < $min) {
                return show(config('code.error'), '由于该档案购买过付费项目，修改功能受限，改后时间不能与原档案时间差超过两个小时');
            }

        }
        try
        {
            // 更新档案
            Recode::where(['uid' => $uid, 'isself' => 1])->update($data);
        } catch (\Exception $e) {
            return show(config('code.error'), $e->getMessage(), [], 500);
        }
        $array = [
            'id'             => $recode_old['id'],
            'cid'            => $recode_cat_id,
            'uid'            => $recode_old['uid'],
            'aid'            => $recode_old['aid'],
            'isself'         => $recode_old['isself'],
            'name'           => $recode_old['name'],
            'type'           => $recode_old['type'],
            'year'           => $year,
            'month'          => $month,
            'day'            => $day,
            'hour'           => $hour,
            'minute'         => $minute,
            'timezone'       => $timezone,
            'birth_country'  => $recode_old['birth_country'],
            'birth_province' => $recode_old['birth_province'],
            'birth_city'     => $recode_old['birth_city'],
            'live_country'   => $recode_old['live_country'],
            'live_province'  => $recode_old['live_province'],
            'live_city'      => $recode_old['live_city'],
            'status'         => $recode_old['status'],
            'comments'       => $recode_old['comments'],
            'long_deg'       => $recode_old['long_deg'],
            'long_min'       => $recode_old['long_min'],
            'ew'             => $recode_old['ew'],
            'lat_deg'        => $recode_old['lat_deg'],
            'lat_min'        => $recode_old['lat_min'],
            'ns'             => $recode_old['ns'],
            'is_summer'      => $is_summer,
            'avatar'         => $recode_old['avatar'],
            'from'           => $recode_old['from'],
        ];

        $longitude = ($recode_old['long_deg'] + $recode_old['long_min'] / 60) * $recode_old['ew'];
        $latitude  = ($recode_old['lat_deg'] + $recode_old['lat_min'] / 60) * $recode_old['ns'];
        // 查询当前星盘日月水金火木土等星落座落宫存入数据库
        $astro_data = getTheRecodeAstro($year, $month, $day, $hour, $minute, $longitude, $latitude, $timezone);
        try
        {
            DB::table('recode_astro')->where(['id' => $recode_old['aid']])->update($astro_data); // 更新档案行星数据
        } catch (\Exception $e) {
            return show(config('code.error'), $e->getMessage(), [], 500);
        }

        // 档案更新时更新用户档案缓存
        Cache::forget('recode_' . $recode_old['id']);
        // 档案更新时更新用户档案日月升缓存
        Cache::forget('recode_astro_' . $recode_old['id']);

        //将档案购买的年运订单重新加入队列
        $this->fortune_redis_job(['rid' => $recode_old['id'], 'uid' => $recode_old['uid']]);

        return show(200, 'ok', array_merge($array, $astro_data));
    }

    public function alter_addr(Request $request)
    {
        if (!Request()->isMethod('put')) {
            return show(config('code.error'), '未知操作', [], 403);
        }
        $uid      = $request->uid;
        $country  = $request->input('birth_country');
        $province = $request->input('birth_province');
        $city     = $request->input('birth_city');
        $longd    = $request->input('long_deg');
        $longm    = $request->input('long_min');
        $ew       = $request->input('ew');
        $latd     = $request->input('lat_deg');
        $latm     = $request->input('lat_min');
        $ns       = $request->input('ns');
        if ($longd < 0 || $longd > 180) {
            return show(10723, 'Long_deg Invalid.');
        }

        if ($longm < 0 || $longm > 59) {
            return show(10724, 'Long_min Invalid.');
        }

        if ($latd < 0 || $latd > 90) {
            return show(10725, 'Lat_deg Invalid.');
        }

        if ($latm < 0 || $latm > 59) {
            return show(10726, 'Lat_min Invalid.');
        }

        if ($ew != 1 && $ew != -1) {
            return show(10728, 'Ew Invalid.');
        }

        if ($ns != 1 && $ns != -1) {
            return show(10729, 'Ns Invalid.');
        }

        $data = [
            'birth_country'  => $country,
            'birth_province' => $province,
            'birth_city'     => $city,
            'long_deg'       => $longd,
            'long_min'       => $longm,
            'ew'             => $ew,
            'lat_deg'        => $latd,
            'lat_min'        => $latm,
            'ns'             => $ns,
        ];

        // 获取档案信息
        $recode_old = $this->RecodeModel->getSelfRecode(['uid' => $uid]);
        //获取档案所属档案袋id
        $recode_cat_id = $this->RecodeCatModel->getRecodeCatId(['uid' => $uid, 'rid' => $recode_old['id']]);

        try
        {
            // 更新档案
            Recode::where(['uid' => $uid, 'isself' => 1])->update($data);
//             if ($result === false) return json(['code' => 10305, 'msg' => DB::table('app_recode')->getError()]);
        } catch (\Exception $e) {
            return show(config('code.error'), $e->getMessage(), [], 500);
        }
        $array = [
            'id'             => $recode_old['id'],
            'cid'            => $recode_cat_id,
            'uid'            => $recode_old['uid'],
            'aid'            => $recode_old['aid'],
            'isself'         => $recode_old['isself'],
            'name'           => $recode_old['name'],
            'type'           => $recode_old['type'],
            'year'           => $recode_old['year'],
            'month'          => $recode_old['month'],
            'day'            => $recode_old['day'],
            'hour'           => $recode_old['hour'],
            'minute'         => $recode_old['minute'],
            'timezone'       => $recode_old['timezone'],
            'birth_country'  => $country,
            'birth_province' => $province,
            'birth_city'     => $city,
            'live_country'   => $recode_old['live_country'],
            'live_province'  => $recode_old['live_province'],
            'live_city'      => $recode_old['live_city'],
            'status'         => $recode_old['status'],
            'comments'       => $recode_old['comments'],
            'long_deg'       => $longd,
            'long_min'       => $longm,
            'ew'             => $ew,
            'lat_deg'        => $latd,
            'lat_min'        => $latm,
            'ns'             => $ns,
            'is_summer'      => $recode_old['is_summer'],
            'avatar'         => $recode_old['avatar'],
            'from'           => $recode_old['from'],
        ];
        $longitude = ($longd + $longm / 60) * $ew;
        $latitude  = ($latd + $latm / 60) * $ns;
        // 查询当前星盘日月水金火木土等星落座落宫存入数据库
        $astro_data = getTheRecodeAstro($recode_old['year'], $recode_old['month'], $recode_old['day'], $recode_old['hour'], $recode_old['minute'], $longitude, $latitude, $recode_old['timezone']);
        try
        {
            DB::table('recode_astro')->where(['id' => $recode_old['aid']])->update($astro_data); // 更新档案行星数据
        } catch (\Exception $e) {
            return show(config('code.error'), $e->getMessage(), [], 500);
        }

        // 档案更新时更新用户档案缓存
        Cache::forget('recode_' . $recode_old['id']);
        // 档案更新时更新用户档案日月升缓存
        Cache::forget('recode_astro_' . $recode_old['id']);

        //将档案购买的年运订单重新加入队列
        $this->fortune_redis_job(['rid' => $recode_old['id'], 'uid' => $recode_old['uid']]);

        return show(200, 'ok', array_merge($array, $astro_data));
    }

    /**修改档案昵称
     * @return \think\response\Json
     */
    public function alter_name(Request $request)
    {
        if (!Request()->isMethod('put')) {
            return show(config('code.error'), '未知操作', [], 403);
        }

        $uid = $request->uid;

        $where = ['uid' => $uid, 'isself' => 1];
        $name  = htmlspecialchars($request->input('name'));
        if ($name == "" || mb_strlen($name, 'utf8') > 10) {
            return show(config('code.error'), '昵称无效', []);
        }
       $result =contentCensor($name);
       if ($result['status'] === 2) {
           // \Log::info('占卜错误:' . $validate->getError());
            return show(config('code.error'), $result['msg']);
        }
        $validate  = new \App\Tools\Validates\Info();
        $a['name'] = $name;
        if ($validate->check($a) !== true) {
            return show(config('code.error'), $validate->getError(), [], 400);
        }
        try
        {
            Recode::where($where)->update(['name' => trim($name)]);
        } catch (\Exception $e) {
            return show(config('code.error'), $e->getMessage(), [], 500);
        }
        try
        {
            User::where('id', $uid)->update(['nickname' => trim($name)]);
        } catch (\Exception $e) {
            return show(config('code.error'), $e->getMessage(), [], 500);
        }

        $recode_info = $this->RecodeModel->getSelfRecode(['uid' => $uid]);

        // 档案更新时更新用户档案缓存
        Cache::forget('recode_' . $recode_info['id']);
        // 档案更新时更新用户档案日月升缓存
        Cache::forget('recode_astro_' . $recode_info['id']);

        return show(200, 'ok', []);
    }

    /**修改档案头像
     * @return \think\response\Json
     */
    public function alter_avatar(Request $request)
    {
        if (!Request()->isMethod('put')) {
            return show(config('code.error'), '未知操作', [], 403);
        }

        $uid    = $request->uid;
        $where  = ['uid' => $request->uid, 'isself' => 1];
        $avatar = $request->input('avatar');

        try
        {
            Recode::where($where)->update(['avatar' => $avatar]);
        } catch (\Exception $e) {
            return show(config('code.error'), $e->getMessage(), [], 500);
        }
        try
        {
            User::where('id', $uid)->update(['avatar' => $avatar]);
        } catch (\Exception $e) {
            return show(config('code.error'), $e->getMessage(), [], 500);
        }

        $recode_info = $this->RecodeModel->getSelfRecode(['uid' => $uid]);

        // 档案更新时更新用户档案缓存
        Cache::forget('recode_' . $recode_info['id']);
        // 档案更新时更新用户档案日月升缓存
        Cache::forget('recode_astro_' . $recode_info['id']);

        return show(200, 'ok', []);
    }

    /**将档案购买的年运订单重新加入队列,并将订单状态改为1=>待计算
     * @param array $data
     * @throws \app\common\lib\exception\ApiException
     */
    public function fortune_redis_job($data = [])
    {
        $rid = $data['rid'];
        $uid = $data['uid'];

        $recode_info = [];

        // 获取档案信息
        $recode_info[] = $this->RecodeModel->getSelfRecode(['uid' => $uid]);

        //获取当前档案解锁的
        $ordersModel = new Orders();
        $map         = ['f.rids' => ['like', "%" . $rid . "%"], 'o.status' => ['in', [1, 4]], 'og.gid' => ['in', config('goods.month_year_id')]];
        try {
            $orders = $ordersModel->from('orders as o')
                ->select('f.time', 'f.type as ftype', 'f.rids', 'g.expire_time', 'o.id as oid', 'o.order_id', 'o.status as ostatus')
                ->join('orders_goods as og', 'o.id', '=', 'og.oid', 'INNER')
                ->join('goods as g', 'og.gid', '=', 'g.id', 'INNER')
                ->join('fortune as f', 'o.fid', '=', 'f.id', 'INNER')
                ->where($map)
                ->get();
            $orders = json_decode(json_encode($orders, true), true);
        } catch (\Exception $e) {
            $orders = [];
        }

        if ($orders || empty($orders)) {
            $oid      = [];
            $order_id = [];
            foreach ($orders as $v) {
                $oid[]       = $v['oid'];
                $order_id[]  = $v['order_id'];
                switch ($v['ftype'])
                {
                    case 2:
                        $start_time = date('Y-m', $v['time']);
                        $end_time = date('Y-m',strtotime($v['expire_time'],$v['time']) - 86400*30);
                        break;
                    case 3:
                        $start_time = date('Y', $v['time']);
                        $end_time = date('Y',strtotime($v['expire_time'],$v['time']) - 86400*365);
                        break;
                    default:
                        $start_time = "";
                        $end_time = "";
                }

                $unlock_time = prDates(['start' => $start_time, 'end' => $end_time, 'type' => $v['ftype']]);


                //将运势加入队列运算
                fortune_redis_job(['oid' => $v['oid'], 'recode_info' => $recode_info, 'unlock_time' => $unlock_time, 'ostatus' => 1, 'ftype' => $v['ftype']]);
            }

            try {
                //将订单状态修改为1
                $ordersModel->where('id', $oid)->update(['status' => 1]);
            } catch (\Exception $e) {
                return show(config('code.error'), '即将进行重新计算,请稍等');
            }

            //删除订单缓存
            foreach ($order_id as $value) {
                $ordersModel->rm_cache(['order_id' => $value]);
            }
        }

    }

}
